Current Sprint: 2. 實作遊戲開始
repo: https://github.com/side-project-at-SPT/ithome-ironman-2024-san-juan
swagger docs: https://side-project-at-spt.github.io/ithome-ironman-2024-san-juan/
玩家依序從牌庫抽取四張卡片,作為手牌
決定起始玩家
規則書有個變體是:每位玩家抽取
(4 + n(順位))
張卡片,並棄至剩 4 張,作為起始手牌
因此,我們將決定起始玩家
的時機調整到發牌前,方便變體實作
choose_starting_player
實體方法starting_player
# app/models/game.rb
class Game < ApplicationRecord
# ...
def start_new_game(seed: nil)
game = new(status: :playing)
# 1. generate a random seed
game.seed = seed || SecureRandom.hex(16)
game.save
# 1.1. generate players
game.game_data[:players] = generate_players(seed: game.seed).to_json
game.game_data[:current_player_index] = 0
game.save
# ...
end
def generate_players(seed: nil)
srand(seed.to_i(16)) if seed
human_player = Player.new(1, [], [])
bot_players = 3.times.map { |i| Player.new(i + 2, [], []) }
([ human_player ] + bot_players).shuffle
end
# ...
end
# app/models/game.rb
class Game < ApplicationRecord
# ...
def start_new_game(seed: nil)
# ...
# 3.3. shuffle the remaining cards to form a supply pile
deck.shuffle!
# 4. Give each player 1 indigo plant as their initial building
players = game.players
players.each do |player|
player.buildings += [ Building.new("01") ]
end
# 5. deal 4 cards to each player as their initial hand, hidden from other players
players.each do |player|
player.hand = deck.shift(4)
end
# save the game data
game.game_data[:players] = players.to_json
game.game_data[:supply_pile] = deck
game.save
# ...
end
# ...
end
1
["0", "0", "0", "0"]
110 - 4 - 4 * 4 = 90
# spec/requests/api/v1/games_spec.rb
# ...
response '200', 'Game created' do
schema type: :object,
properties: {
id: { type: :integer },
status: { type: :string }
},
required: [ 'id', 'status' ]
run_test! do
json = JSON.parse(response.body)
expect(json['status']).to eq('playing')
expect(json['game_config']['seed']).to eq('1234567890abcdef')
expect(json['game_data']['current_price']).to match_array([ 1, 2, 2, 2, 3 ])
expect(json['game_data']['supply_pile'].size).to eq(110 - 4 - 4 * 4)
# pp json['game_data']['supply_pile'].index { |card| card == '01' }
expect(json['game_data']['supply_pile'][27]).to eq("01")
expect(json['game_data']['players'].size).to eq(4)
expect(json['game_data']['players'][0]['buildings'].size).to eq(1)
expect(json['game_data']['players'][0]['buildings'][0]['id']).to eq("01")
# pp json['game_data']['players'].map { |player| player['id'] }
expect(json['game_data']['current_player_index']).to eq(0)
expect(json['game_data']['players'][0]['id']).to eq(1)
expect(json['game_data']['players'][0]['hand'].size).to eq(4)
expect(json['game_data']['players'][0]['hand']).to match_array([ "00", "00", "00", "00" ])
end
end
# ...
# app/views/api/v1/games/_game.json.jbuilder
# ...
json.game_data do
# ...
json.current_player_index game.game_data["current_player_index"]
# ...
end
# ...
rails s
# open another session
curl localhost:3000/api/v1/games -d '' | jq
{
"id": 5,
"status": "playing",
"game_config": {
"seed": "b860708c2dc20e1541a03054ee435951"
},
"game_data": {
"current_price": [
1,
1,
1,
2,
2
],
"supply_pile": [], // 略
"current_player_index": 0,
"players": [
{
"id": 1,
"hand": [
"00",
"00",
"00",
"00"
],
"buildings": [
{
"id": "01"
}
]
},
{
"id": 2,
"hand": [
"01",
"00",
"00",
"00"
],
"buildings": [
{
"id": "01"
}
]
},
{
"id": 4,
"hand": [
"00",
"00",
"00",
"00"
],
"buildings": [
{
"id": "01"
}
]
},
{
"id": 3,
"hand": [
"00",
"00",
"01",
"00"
],
"buildings": [
{
"id": "01"
}
]
}
]
}
}
收工.
還沒完成的項目有:
預估每一種回合階段花 2-3 天、行動權轉換 1-2 天、計分 1 天
=> 3 * 5 + 2 + 1 = 18
不含其它的卡片實作
以上不代表明天會做,如有雷同純屬巧合
SPT (Side Project Taiwan) 的宗旨是藉由Side Project開發來成就自我,透過持續學習和合作,共同推動技術和專業的發展。我們相信每一個參與者,無論是什麼專業,都能在這個社群中找到屬於自己的成長空間。
歡迎所有對Side Project開發有興趣的人加入我們,可以是有點子來找夥伴,也可以是來尋找有興趣的Side Project加入,邀請大家一同打造一個充滿活力且有意義的技術社群!
Discord頻道連結:https://sideproj.tw/dc